package com.gzhryc.net_marketing.cloud.business.services;

import java.sql.SQLException;
import java.util.Date;
import java.util.List;

import com.gzhryc.common.DateTools;
import com.gzhryc.common.NumberTools;
import com.gzhryc.common.StringTools;
import com.gzhryc.common.api.DefaultAPICodeConstants;
import com.gzhryc.common.event.DelayHandleService;
import com.gzhryc.common.exceptions.LogicException;
import com.gzhryc.common.json.JsonTools;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.jdbc.Conditions;
import com.gzhryc.jdbc.JdbcSession;
import com.gzhryc.jdbc.MultiDBTools;
import com.gzhryc.net_marketing.api.CloudGoodsOrderAPIService;
import com.gzhryc.net_marketing.api.protocol.order.UpdateGoodsOrderAddressRequest;
import com.gzhryc.net_marketing.api.protocol.order.UpdateGoodsOrderAddressResponse;
import com.gzhryc.net_marketing.cloud.business.PayConfig;
import com.gzhryc.net_marketing.cloud.business.TradeNoUtils;
import com.gzhryc.net_marketing.cloud.business.dao.PayGoodsOrderDao;
import com.gzhryc.net_marketing.cloud.business.dao.db.PayGoodsOrder;
import com.gzhryc.net_marketing.cloud.business.dao.db.TeamPayApply;
import com.gzhryc.net_marketing.cloud.business.dao.db.TeamPayApplyMember;
import com.gzhryc.net_marketing.cloud.business.dao.enums.PayGoodsOrderEnum;
import com.gzhryc.net_marketing.cloud.business.dao.enums.PayGoodsOrderLogEnum;
import com.gzhryc.net_marketing.cloud.business.dao.enums.TeamPayApplyMemberEnum;
import com.gzhryc.net_marketing.cloud.business.dao.models.TeamPayOrderStateCount;
import com.gzhryc.net_marketing.cloud.business.event.PayOrderLogEvent;
import com.gzhryc.net_marketing.cloud.business.services.dto.PayGoodsOrderSearch;
import com.gzhryc.net_marketing.cloud.business.services.models.CouponContent;
import com.gzhryc.net_marketing.cloud.business.services.models.PayGoodsOrderLogItem;
import com.gzhryc.net_marketing.cloud.goods.dao.db.Goods;
import com.gzhryc.net_marketing.cloud.goods.dao.db.GoodsSpace;
import com.gzhryc.net_marketing.cloud.goods.dao.enums.GoodsEnum;
import com.gzhryc.net_marketing.cloud.goods.services.GoodsService;
import com.gzhryc.net_marketing.cloud.goods.services.GoodsSpaceService;
import com.gzhryc.net_marketing.cloud.logistics.LogisticsCostUtils;
import com.gzhryc.net_marketing.core.enums.ELockState;
import com.gzhryc.net_marketing.core.enums.EReceiveGoodsType;
import com.gzhryc.net_marketing.core.enums.GoodsOrderEnum;
import com.gzhryc.pay.adaptation.weixin.WXPayNormalPayService;
import com.gzhryc.pay.adaptation.weixin.enums.EWXPayNormalRefundState;
import com.gzhryc.pay.adaptation.weixin.msg.normal.WXPayNormalRefundResponse;
import com.gzhryc.pay.enums.TradeType;
import com.gzhryc.shared_device.base.ILogisticsCostConfig;
import com.gzhryc.shared_device.base.enums.EPayState;
import com.gzhryc.shared_device.base.enums.EPayType;
import com.gzhryc.shared_device.base.models.OperateInfo;
import com.gzhryc.shared_device.common.payment.dao.db.WXPayOrder;
import com.gzhryc.shared_device.common.payment.dao.db.WXRefundOrder;
import com.gzhryc.shared_device.common.payment.dao.db.WalletPayOrder;
import com.gzhryc.shared_device.common.payment.dao.db.WalletRefundOrder;
import com.gzhryc.shared_device.common.payment.services.WXPayOrderService;
import com.gzhryc.shared_device.common.payment.services.WXRefundOrderService;
import com.gzhryc.shared_device.common.payment.services.WalletPayOrderService;
import com.gzhryc.shared_device.common.payment.services.WalletRefundOrderService;
import com.gzhryc.shared_device.oem.code.BaseConstants;
import com.gzhryc.shared_device.oem.code.business.EBusinessType;
import com.gzhryc.shared_device.oem.code.config.dao.db.LogisticsCompany;
import com.gzhryc.shared_device.oem.code.config.services.LogisticsCompanyService;
import com.gzhryc.shared_device.oem.code.config.services.LogisticsCostConfigService;
import com.gzhryc.shared_device.oem.code.member.dao.db.Member;
import com.gzhryc.shared_device.oem.code.member.dao.db.MemberAddress;
import com.gzhryc.shared_device.oem.code.member.dao.db.MemberWallet;
import com.gzhryc.shared_device.oem.code.member.services.MemberWalletService;

public class PayGoodsOrderService {

	static Logger log = Logger.getLogger(PayGoodsOrderService.class);

	public static PayGoodsOrderService self() {
		return MultiDBTools.getService(PayGoodsOrderService.class, true);
	}

	public static PayGoodsOrderService self(String jdbcKey) {
		return MultiDBTools.getService(jdbcKey, PayGoodsOrderService.class, true);
	}

	PayGoodsOrderDao dao;

	public PayGoodsOrderService(String jdbcKey) {
		dao = new PayGoodsOrderDao(jdbcKey);
	}

	public List<PayGoodsOrder> findBySearch(PayGoodsOrderSearch search, Integer pageNo, Integer pageLimit) {
		Conditions condition = dao.buildConditions(search);
		condition.and().le("createDate",search.getEndDate());
		condition.and().ge("supplyState",search.getMinSupplyState());
		condition.desc("createDate");
		
		try {
			return dao.findByCondition(condition, pageNo, pageLimit);
		} catch (SQLException e) {
			log.error(e.getMessage(), e);
		}
		return null;
	}

	public Long countBySearch(PayGoodsOrderSearch search){
		Conditions condition = dao.buildConditions(search);
		condition.and().le("createDate",search.getEndDate());
		condition.and().ge("supplyState",search.getMinSupplyState());

		try {
			return dao.count(condition);
		} catch (SQLException e) {
			log.error(e.getMessage(), e);
		}
		return 0L;
	}

	public List<TeamPayOrderStateCount> findStateCountByMemberId(Long memberId){
		if(memberId != null){
			Conditions conditions = new Conditions(PayGoodsOrder.class);
			conditions.and().is("memberId",memberId);
			try {
				return dao.countByGroupState(conditions);
			} catch (SQLException e) {
				log.error(e.getMessage(),e);
			}
		}
		return null;
	}

	public Long countByMemberId(Long memberId){
		if(memberId != null){
			Conditions conditions = new Conditions(PayGoodsOrder.class);
			conditions.and().is("memberId",memberId);

			try {
				return dao.count(conditions);
			} catch (SQLException e) {
				log.error(e.getMessage(), e);
			}
		}
		return 0L;
	}

	public PayGoodsOrder getJoinByTradeNo(String tradeNo) {
		if (StringTools.isNotBlank(tradeNo)) {
			try {
				return dao.getJoinById(tradeNo);
			} catch (SQLException e) {
				log.error(e.getMessage(), e);
			}
		}
		return null;
	}

	public PayGoodsOrder getByTradeNo(String tradeNo) {
		if (StringTools.isNotBlank(tradeNo)) {
			try {
				return dao.getById(tradeNo);
			} catch (SQLException e) {
				log.error(e.getMessage(), e);
			}
		}
		return null;
	}

	public PayGoodsOrder getByTradeNo(String tradeNo, Long memberId) {
		if (StringTools.isNotBlank(tradeNo) && memberId != null) {
			Conditions conditions = new Conditions(PayGoodsOrder.class);
			conditions.and().is("tradeNo",tradeNo);
			conditions.and().is("memberId",memberId);
			try {
				return dao.get(conditions);
			} catch (SQLException e) {
				log.error(e.getMessage(), e);
			}
		}
		return null;
	}

	public PayGoodsOrder getWaitingByGoodsIdAndMemberId(Long goodsId, Long memberId){
		if(goodsId != null && memberId != null){
			Conditions condition = new Conditions(PayGoodsOrder.class);
			condition.and().is("goodsId",goodsId);
			condition.and().is("memberId",memberId);
			condition.and().is("state", GoodsOrderEnum.State.Wait.index());

			try {
				return dao.get(condition);
			} catch (SQLException e) {
				log.error(e.getMessage(), e);
			}
		}
		return null;
	}

	public PayGoodsOrder payTeamApplyMember(TeamPayApply payApply, TeamPayApplyMember payApplyMember) throws LogicException {
		if(payApplyMember != null && payApplyMember.getGoodsId() != null){
			Goods goods = GoodsService.self().getById(payApplyMember.getGoodsId());
			if (goods == null) {
				throw new LogicException("商品不存在");
			}
			GoodsSpace goodsSpace = null;
			if(payApplyMember.getGoodsSpaceId() != null) {
				goodsSpace = GoodsSpaceService.self().getByKeys(goods.getId()
						, payApplyMember.getGoodsSpaceId());
				if (goodsSpace == null) {
					throw new LogicException("商品的规格不存在");
				}
			}

			PayGoodsOrder goodsPayOrder = new PayGoodsOrder();
			goodsPayOrder.setTradeNo(payApplyMember.getBusinessTradeNo());
			goodsPayOrder.setMemberId(payApplyMember.getMemberId());
			goodsPayOrder.setMemberNickname(payApplyMember.getMemberNickname());
			goodsPayOrder.setMemberPhone(payApplyMember.getMemberPhone());
			goodsPayOrder.setBusinessType(PayGoodsOrderEnum.BusinessType.TeamPay.index());
			goodsPayOrder.setApplyId(payApply.getId());
			goodsPayOrder.setGoodsId(goods.getId());
			if(goodsSpace != null) {
				goodsPayOrder.setGoodsSpaceId(goodsSpace.getId());
				goodsPayOrder.setGoodsSpaceName(goodsSpace.getName());
			}
			goodsPayOrder.setGoodsCode(goods.getCode());
			goodsPayOrder.setTypeCodes(goods.getTypeCodes());
			goodsPayOrder.setTypeNames(goods.getTypeNames());
			goodsPayOrder.setGoodsName(goods.getName());
			goodsPayOrder.setGoodsImg(goods.getThumbnailImg());
			goodsPayOrder.setGoodsMoney(goods.getPayMoney());
			goodsPayOrder.setGoodsCount(payApplyMember.getGoodsCount());
			goodsPayOrder.setClassify(goods.getClassify());	//商品类别，支持虚拟商品
			goodsPayOrder.setLogisticsMoney(payApplyMember.getLogisticsMoney());
			goodsPayOrder.setMoney(payApplyMember.getPayMoney());
			goodsPayOrder.setPayType(payApplyMember.getPayType());
			goodsPayOrder.setRewardMoney(0);
			goodsPayOrder.setWalletMoney(0);
			goodsPayOrder.setPayMoney(payApplyMember.getPayMoney());
			if(TeamPayApplyMemberEnum.PayState.Success.index().equals(payApplyMember.getPayState())){
				goodsPayOrder.setState(GoodsOrderEnum.State.WaitDeliver.index());
			}else {
				goodsPayOrder.setState(GoodsOrderEnum.State.Wait.index());
			}
			goodsPayOrder.setSupplyState(GoodsOrderEnum.SupplyState.WaitConfirm.index());
			goodsPayOrder.setMailAddressId(payApplyMember.getMailAddressId());
			goodsPayOrder.setReceiveName(payApplyMember.getReceiveName());
			goodsPayOrder.setReceivePhone(payApplyMember.getReceivePhone());
			goodsPayOrder.setReceiveProvince(payApplyMember.getReceiveProvince());
			goodsPayOrder.setReceiveAddress(payApplyMember.getReceiveAddress());
			goodsPayOrder.setLogisticsCompanyId(payApplyMember.getLogisticsCompanyId());
			goodsPayOrder.setLogisticsCompany(payApplyMember.getLogisticsCompany());
			goodsPayOrder.setCreateDate(new Date());

			try {
				if (dao.insert(goodsPayOrder) > 0) {
					return goodsPayOrder;
				}
			} catch (SQLException e) {
				log.error(e.getMessage(),e);
			}
		}
		return null;
	}

	/**
	 * 再次支付,只有第三分支付才存在再次支付
	 * @param simpleTeamPayOrder
	 * @param payConfig
	 * @return
	 */
	public boolean againComposePayGoods(PayGoodsOrder goodsOrder, PayConfig payConfig, OperateInfo operateInfo) throws LogicException {
		if(goodsOrder != null && StringTools.isNotBlank(goodsOrder.getTradeNo())
				&& GoodsOrderEnum.State.Wait.index().equals(goodsOrder.getState()) && payConfig != null) {
			Long goodsId = goodsOrder.getGoodsId();
			Long goodsSpaceId = goodsOrder.getGoodsSpaceId();
			Goods goods = GoodsService.self().getById(goodsId);
			if (goods == null) {
				throw new LogicException("商品不存在");
			}
			if (GoodsEnum.State.OffTheShelf.index().equals(goods.getState())) {
				throw new LogicException("商品已下架");
			} else if (GoodsEnum.State.NoInventory.index().equals(goods.getState())) {
				throw new LogicException("商品暂无库存");
			}
			GoodsSpace goodsSpace = null;
			if (goodsSpaceId != null) {
				goodsSpace = GoodsSpaceService.self().getByKeys(goods.getId(), goodsSpaceId);
				if (goodsSpace == null) {
					throw new LogicException("商品的规格不存在");
				}
			}
			
			if(goodsOrder.getPayMoney() > 0 && EPayType.WXPay.index().equals(goodsOrder.getPayType())){
				boolean isCreate = false;
				WXPayOrder payOrder = WXPayOrderService.self(BaseConstants.JDBC_KEY, goodsOrder.getCreateDate()).getLastByBusinessTradeNo(goodsOrder.getTradeNo());
				if(payOrder != null){
					if(!payOrder.getPayMoney().equals(payConfig.getPayMoney())){
						//价格不一致弃用，创建新的
						isCreate = true;
					}else if(payOrder.getPayDate() != null){
						Long hour = DateTools.differenceHour(payOrder.getPayDate(),new Date());
						if(hour < 2){
							//超过两小时弃用，创建新的
							isCreate = true;
						}
					}else{
						log.warn("{{0}}订单未触发第三方支付，复用",payOrder.getTradeNo());
					}
				}

				if(payOrder != null && isCreate){
					//存在并创建信息的支付信息，旧的支付需要关闭
					if(!WXPayOrderService.self(BaseConstants.JDBC_KEY, goodsOrder.getCreateDate()).closeWaitPay(payOrder)){
						log.error("关闭旧的失效的支付订单失败，订单号：{{0}}",payOrder.getTradeNo());
					}
					payOrder = null;
				}

				if(payOrder == null) {
					payOrder = new WXPayOrder();
					payOrder.setTradeNo(TradeNoUtils.createPayTradeNo(goodsOrder.getTradeNo(),goodsOrder.getCreateDate()));
					payOrder.setTitle("购买"+goods.getTypeNames()+"商品");
					payOrder.setBusinessType(EBusinessType.MARKET.index());
					payOrder.setBusinessTypeName(EBusinessType.MARKET.note());
					payOrder.setBusinessTradeNo(goodsOrder.getTradeNo());
					payOrder.setAppType(payConfig.getAppType());
					payOrder.setAppId(payConfig.getAppId());
					payOrder.setPayerId(payConfig.getPayerId());
					payOrder.setBusinessAccount(payConfig.getBusinessAccount());
					payOrder.setTradeType(TradeType.Normal.name());
					payOrder.setPayMoney(payConfig.getPayMoney());
					payOrder.setClientIP(payConfig.getClientIP());
					payOrder.setNotifyUrl(payConfig.getNotifyUrl());
					payOrder.setPayStatus(EPayState.Wait.index());
					payOrder.setCreateDate(goodsOrder.getCreateDate());
					//保存订单
					if(WXPayOrderService.self(BaseConstants.JDBC_KEY, payOrder.getCreateDate()).add(payOrder)){
						return true;
					}else {
						throw new LogicException("保存微信支付订单失败");
					}
				}else {
					return true;
				}
			}else {
				throw new LogicException("不支持的支付类型");
			}
		}
		return false;
	}

	/**
	 * 组合支付方式直接购买商品
	 * @param member
	 * @param goodsId
	 * @param payConfig
	 * @return
	 * @throws LogicException
	 */
	public PayGoodsOrder composePayGoods(Member member,Goods goods,GoodsSpace goodsSpace, Integer goodsCount
			, PayConfig payConfig,OperateInfo operateInfo) throws LogicException {
		if (member != null && goods != null && goodsCount > 0 && payConfig != null) {
			if (payConfig.getRewardMoney() == null || payConfig.getPayMoney() == null || payConfig.getWalletMoney() == null) {
				throw new LogicException("支付金额缺失");
			}
			if (payConfig.getMailAddress() == null) {
				throw new LogicException("收货地址不存在");
			}

			//计算商品价格
			Integer money = goods.getPayMoney() * goodsCount;

			ILogisticsCostConfig logisticsCostConfig = null;
			Integer logisticsMoney = 0;		//物流费

			if(goods.getSupplierId() != null){
				logisticsCostConfig = LogisticsCostUtils.getUsableConfig(goods.getSupplierId()
						, payConfig.getLogisticsCompanyId(), payConfig.getMailAddress().getProvince());
				if (logisticsCostConfig == null) {
					throw new LogicException("未找到物流价格配置");
				}
				//使用批发价
				Integer wholesaleMoney = goods.getWholesaleMoney() * goodsCount;
				if (!LogisticsCostUtils.isFree(logisticsCostConfig,wholesaleMoney)) {
					logisticsMoney = logisticsCostConfig.getMoney();;
				}
			}else {
				//使用系统物流费用
				logisticsCostConfig = LogisticsCostConfigService.self(BaseConstants.JDBC_KEY)
						.getUsableConfig(payConfig.getLogisticsCompanyId(), payConfig.getMailAddress().getProvince());
			}
			
			if (logisticsCostConfig == null) {
				throw new LogicException("未找到物流价格配置");
			}

			money = money + logisticsMoney;

			//获取优惠金额
			Integer couponMoney = 0;
			CouponContent couponContent = null;
			/*if(payConfig.getCouponMemberRecord() != null){
				if(payConfig.getCouponMemberRecord().getMinimumCharge() > 0 && payConfig.getCouponMemberRecord().getMinimumCharge() < money){
					throw new LogicException("该优惠券未到达最低消费标准");
				}
				if(CouponActivityEnum.CouponType.Discount.index().equals(payConfig.getCouponMemberRecord().getCouponType())){
					couponMoney = NumberTools.discount(money,payConfig.getCouponMemberRecord().getCouponDiscount());
				}else{
					couponMoney = payConfig.getCouponMemberRecord().getCouponMoney();
				}

				couponContent = new CouponContent();
				couponContent.setCouponId(payConfig.getCouponMemberRecord().getId());
				couponContent.setCouponType(payConfig.getCouponMemberRecord().getCouponType());
				couponContent.setCouponMoney(payConfig.getCouponMemberRecord().getCouponMoney());
				couponContent.setCouponDiscount(payConfig.getCouponMemberRecord().getCouponDiscount());
			}*/

			//检查组合金额是否OK
			Integer composeMoney = payConfig.getRewardMoney() + payConfig.getWalletMoney() + payConfig.getPayMoney() - couponMoney;;
			if(money > composeMoney){
				throw new LogicException("支付金额不足，请重新选择");
			}else if(money < composeMoney){
				throw new LogicException("支付金额超出，请重新选择");
			}

			Integer payType = EPayType.WXComposePay.index(); //默认组合支付
			if(payConfig.getWalletMoney() == 0 && payConfig.getRewardMoney() == 0){
				payType = EPayType.WXPay.index();
			}else if(payConfig.getPayMoney() == 0 && payConfig.getRewardMoney() == 0){
				payType = EPayType.EWallet.index();
			}

			PayGoodsOrder goodsPayOrder = new PayGoodsOrder();
			goodsPayOrder.setTradeNo(TradeNoUtils.createTradeNo());
			goodsPayOrder.setMemberId(member.getId());
			goodsPayOrder.setMemberNickname(member.getNickname());
			goodsPayOrder.setMemberPhone(member.getPhone());
			goodsPayOrder.setBusinessType(PayGoodsOrderEnum.BusinessType.DirectPay.index());
			goodsPayOrder.setProjectId(payConfig.getProjectId());
			goodsPayOrder.setGoodsId(goods.getId());
			if(goodsSpace != null) {
				goodsPayOrder.setGoodsSpaceId(goodsSpace.getId());
				goodsPayOrder.setGoodsSpaceName(goodsSpace.getName());
			}
			goodsPayOrder.setGoodsCode(goods.getCode());
			goodsPayOrder.setTypeCodes(goods.getTypeCodes());
			goodsPayOrder.setTypeNames(goods.getTypeNames());
			goodsPayOrder.setGoodsName(goods.getName());
			goodsPayOrder.setGoodsImg(goods.getThumbnailImg());
			goodsPayOrder.setGoodsMoney(goods.getPayMoney());
			goodsPayOrder.setGoodsCount(goodsCount);
			goodsPayOrder.setClassify(goods.getClassify());	//商品类别，支持虚拟商品
			goodsPayOrder.setLogisticsMoney(logisticsMoney);
			goodsPayOrder.setMoney(money);
			goodsPayOrder.setPayType(payType);
			goodsPayOrder.setRewardMoney(payConfig.getRewardMoney());
			goodsPayOrder.setWalletMoney(payConfig.getWalletMoney());
			goodsPayOrder.setPayMoney(payConfig.getPayMoney());
			goodsPayOrder.setCouponMoney(couponMoney);	//优惠金额
			goodsPayOrder.setState(GoodsOrderEnum.State.Wait.index());
			goodsPayOrder.setSupplyState(GoodsOrderEnum.SupplyState.WaitConfirm.index());
			goodsPayOrder.setMailAddressId(payConfig.getMailAddress().getId());
			goodsPayOrder.setReceiveName(payConfig.getMailAddress().getReceiveName());
			goodsPayOrder.setReceivePhone(payConfig.getMailAddress().getReceivePhone());
			goodsPayOrder.setReceiveProvince(payConfig.getMailAddress().getProvince());
			goodsPayOrder.setReceiveAddress(payConfig.getMailAddress().getFullAddress());
			goodsPayOrder.setCreateDate(new Date());

			//物流信息
			goodsPayOrder.setLogisticsCompanyId(logisticsCostConfig.getCompanyId());
			goodsPayOrder.setLogisticsCompany(logisticsCostConfig.getCompanyName());

			//优惠券信息
			/*if(couponContent != null){
				goodsPayOrder.setCouponContent(JsonTools.toJson(couponContent));
			}*/

			JdbcSession.begin();
			try {
				//钱包余额支付
				if(payConfig.getWalletMoney() > 0){
					operateInfo.setOperateNote("支付购买商品订单：" +  goodsPayOrder.getTradeNo());
					Long walletMoney = NumberTools.changeMoneyLi(NumberTools.changeMoney(payConfig.getWalletMoney()));
					
					if(!MemberWalletService.self(BaseConstants.JDBC_KEY).reduceMoney(member.getId(), walletMoney, operateInfo)) {
						throw new LogicException("会员钱包支付失败");
					}
				}
				
				//虚拟币支付
				if(payConfig.getRewardMoney() > 0){
					operateInfo.setOperateNote("支付购买商品订单：" +  goodsPayOrder.getTradeNo());
					Long rewardMoney = NumberTools.changeMoneyLi(NumberTools.changeMoney(payConfig.getRewardMoney()));
					
					if(!MemberWalletService.self(BaseConstants.JDBC_KEY).reduceVMoney(member.getId(), rewardMoney, operateInfo)) {
						throw new LogicException("会员虚拟币支付失败");
					}
				}
				
				if(payConfig.getPayMoney() > 0 && EPayType.WXPay.index().equals(payType)){
					WXPayOrder payOrder = new WXPayOrder();
					payOrder.setTradeNo(TradeNoUtils.createPayTradeNo(goodsPayOrder.getTradeNo(),goodsPayOrder.getCreateDate()));
					payOrder.setTitle("购买"+goods.getTypeNames()+"商品");
					payOrder.setBusinessType(EBusinessType.MARKET.index());
					payOrder.setBusinessTypeName(EBusinessType.MARKET.note());
					payOrder.setBusinessTradeNo(goodsPayOrder.getTradeNo());
					payOrder.setAppType(payConfig.getAppType());
					payOrder.setAppId(payConfig.getAppId());
					payOrder.setPayerId(payConfig.getPayerId());
					payOrder.setBusinessAccount(payConfig.getBusinessAccount());
					payOrder.setTradeType(TradeType.Normal.name());
					payOrder.setPayMoney(payConfig.getPayMoney());
					payOrder.setClientIP(payConfig.getClientIP());
					payOrder.setNotifyUrl(payConfig.getNotifyUrl());
					payOrder.setPayStatus(EPayState.Wait.index());
					payOrder.setCreateDate(goodsPayOrder.getCreateDate());
					//保存订单
					if(!WXPayOrderService.self(BaseConstants.JDBC_KEY, payOrder.getCreateDate()).add(payOrder)){
						throw new LogicException("保存微信支付订单失败");
					}
				}
				
				if (dao.insert(goodsPayOrder) > 0) {
					JdbcSession.commit();
					return goodsPayOrder;
				}
			} catch (SQLException e) {
				log.error(e.getMessage(), e);
			} finally {
				JdbcSession.end();
			}
		}
		return null;
	}

	public boolean toRefundOrder(PayGoodsOrder simpleTeamPayOrder,WXPayNormalPayService payService,OperateInfo operateInfo) throws LogicException{
		if (PayGoodsOrderEnum.BusinessType.TeamPay.index().equals(simpleTeamPayOrder.getBusinessType())) {
			if (setLockState(simpleTeamPayOrder.getTradeNo())) {
				try {
					return toRefundOrderByTeamPay(simpleTeamPayOrder, payService, operateInfo);
				} finally {
					removeLockState(simpleTeamPayOrder.getTradeNo());
				}
			}
		}else {
			if (setLockState(simpleTeamPayOrder.getTradeNo())) {
				try {
					return toRefundOrderByComposePay(simpleTeamPayOrder,payService,operateInfo);
				} finally {
					removeLockState(simpleTeamPayOrder.getTradeNo());
				}
			}
		}
		return false;
	}

	private boolean toRefundOrderByTeamPay(PayGoodsOrder goodsOrder,WXPayNormalPayService payService,OperateInfo operateInfo) throws LogicException{
		TeamPayApplyMember simpleTeamPayApplyMember = TeamPayApplyMemberService.self()
				.getByApplyIdAndMemberId(goodsOrder.getApplyId(),goodsOrder.getMemberId());
		if(simpleTeamPayApplyMember == null){
			throw new LogicException("未找到团拼会员信息");
		}
		if(!TeamPayApplyMemberEnum.PayState.Success.index().equals(simpleTeamPayApplyMember.getPayState())){
			throw new LogicException("团拼会员支付状态为"+simpleTeamPayApplyMember.getPayStateName()+"，无法退款");
		}

		Long rewardMoney = 0L;	//已扣除的奖励金额
		if(simpleTeamPayApplyMember.getRewardMoney() > 0) {
			rewardMoney = NumberTools.changeMoneyLi(NumberTools.changeMoney(simpleTeamPayApplyMember.getRewardMoney()));
			try {
				//减少用户奖励的虚拟币
				if (!MemberWalletService.self().reduceVMoney(simpleTeamPayApplyMember.getMemberId()
						, rewardMoney, operateInfo)) {
					//减少失败，检查可以减少的金额
					MemberWallet wallet = MemberWalletService.self().getByMemberId(simpleTeamPayApplyMember.getMemberId());
					if (wallet == null) {
						throw new LogicException("团拼会员钱包不存在");
					}

					if (wallet.getVirtualMoney() > 0) {
						if (simpleTeamPayApplyMember.getRewardMoney() > wallet.getVirtualMoney()) {
							rewardMoney = simpleTeamPayApplyMember.getRewardMoney() - wallet.getVirtualMoney();
							//触发再次减少
							if (!MemberWalletService.self().reduceVMoney(simpleTeamPayApplyMember.getMemberId()
									, rewardMoney, operateInfo)) {
								rewardMoney = NumberTools.changeMoneyLi(NumberTools.changeMoney(simpleTeamPayApplyMember.getRewardMoney()));
								throw new LogicException("无法减少团拼会员奖励的虚拟币");
							}
						} else {
							throw new LogicException("无法减少团拼会员奖励的虚拟币");
						}
					}
				}
			}catch (Exception e){
				log.error(e.getMessage(),e);
			}
		}

		Integer money = simpleTeamPayApplyMember.getRewardMoney() - NumberTools.changeMoney(NumberTools.changeMoneyLi(rewardMoney));
		if(money < 0){
			throw new LogicException("撤销订单的奖励金额计算错误");
		}

		try {
			if(EPayType.WXPay.index().equals(goodsOrder.getPayType())){
				WXPayOrder payOrder = WXPayOrderService.self(goodsOrder.getCreateDate()).getLastByBusinessTradeNo(goodsOrder.getTradeNo());
				if (payService != null) {
					Integer refundMoney  = payOrder.getReceiptMoney() - money;
					if(refundMoney <= 0){
						throw new LogicException("撤销订单的退款金额计算错误，实收不足扣款");
					}
					WXRefundOrder refundOrder = WXRefundOrderService.self(goodsOrder.getCreateDate()).createRefundOrder(payOrder,refundMoney
							,operateInfo.getOperateNote());
					if (refundOrder != null) {
						WXPayNormalRefundResponse externalResult = payService.applyRefundOrder(refundOrder);
						if (externalResult != null) {
							if (EWXPayNormalRefundState.SUCCESS.name().equals(externalResult.getStatus())) {
								return true;
							} else {
								WXRefundOrderService.self(goodsOrder.getCreateDate()).toFail(refundOrder.getTradeNo(), externalResult.getMessage(),
										JsonTools.toJson(externalResult));
								throw new LogicException("撤销订单请求失败");
							}
						} else {
							throw new LogicException("撤销订单请求未响应");
						}
					} else {
						throw new LogicException("创建退款订单失败");
					}
				} else {
					throw new LogicException("未获取支付服务");
				}
			}
		}catch (Exception e){
			//回滚奖励金额
			if(rewardMoney > 0){
				if(!MemberWalletService.self().addVMoney(simpleTeamPayApplyMember.getMemberId()
						, rewardMoney, operateInfo)){
					log.error("回滚时，无法增加团拼会员奖励的虚拟币，订单：{{0}}",simpleTeamPayApplyMember);
				}
			}
			throw e;
		}
		return false;
	}

	/**
	 * 执行组合支付的退款订单
	 * @param simpleTeamPayOrder
	 * @param operateInfo
	 * @return
	 * @throws LogicException
	 */
	private boolean toRefundOrderByComposePay(PayGoodsOrder goodsOrder,WXPayNormalPayService payService,OperateInfo operateInfo) throws LogicException{
		List<WalletPayOrder> payOrderList = WalletPayOrderService.self(goodsOrder.getCreateDate()).getSuccessByBusinessTradeNo(goodsOrder.getTradeNo());
		if(payOrderList == null || payOrderList.size() == 0){
			throw new LogicException("未找到支付成功的支付订单");
		}
		JdbcSession.begin();
		try {
			//优先处理本地钱包，如果第三方支付失败，则自动回滚本地钱包
			for (WalletPayOrder payOrder : payOrderList) {
				if (EPayType.EVirtual.index().equals(payOrder.getPayType())) {
					WalletRefundOrder refundOrder = WalletRefundOrderService.self(payOrder.getCreateDate()).createRefundOrder(payOrder
							,payOrder.getPayMoney(),operateInfo.getOperateNote());
					if (refundOrder != null) {
						/*MemberWalletVirtualPayService payService = new MemberWalletVirtualPayService();
						MemberWalletRefundOrder externalResult = payService.applyRefundOrder(payOrder, refundOrder);
						if (externalResult != null) {
							if (ERefundState.Success.equals(externalResult.getRefundState())) {
								continue;
							} else {
								//WalletRefundOrderService.self().toFail(refundOrder.getTradeNo(), JsonTools.toJson(externalResult));
								throw new LogicException("撤销虚拟币支付订单请求失败");
							}
						} else {
							throw new LogicException("撤销虚拟币支付订单请求未响应");
						}*/
					}
				}else if (EPayType.EWallet.index().equals(payOrder.getPayType())) {
					WalletRefundOrder refundOrder = WalletRefundOrderService.self(payOrder.getCreateDate()).createRefundOrder(payOrder
							,payOrder.getPayMoney(),operateInfo.getOperateNote());
					if (refundOrder != null) {
						/*MemberWalletNormalPayService payService = new MemberWalletNormalPayService();
						MemberWalletRefundOrder externalResult = payService.applyRefundOrder(payOrder, refundOrder);
						if (externalResult != null) {
							if (ERefundState.Success.equals(externalResult.getRefundState())) {
								continue;
							} else {
								//RefundOrderService.self().toFail(refundOrder.getTradeNo(), JsonTools.toJson(externalResult));
								throw new LogicException("撤销钱包订单请求失败");
							}
						} else {
							throw new LogicException("撤销钱包订单请求未响应");
						}*/
					}
				}
			}
			

			if(EPayType.WXComposePay.index().equals(goodsOrder.getPayType())) {
				WXPayOrder payOrder = WXPayOrderService.self(goodsOrder.getCreateDate()).getLastByBusinessTradeNo(goodsOrder.getTradeNo());
				if (payService != null) {
					WXRefundOrder refundOrder = WXRefundOrderService.self(goodsOrder.getCreateDate())
							.createRefundOrder(payOrder,payOrder.getReceiptMoney(),operateInfo.getOperateNote());
					if (refundOrder != null) {
						WXPayNormalRefundResponse externalResult = payService.applyRefundOrder(refundOrder);
						if (externalResult != null) {
							if (!EWXPayNormalRefundState.SUCCESS.name().equals(externalResult.getStatus())) {
								WXRefundOrderService.self(goodsOrder.getCreateDate()).toFail(refundOrder.getTradeNo(),externalResult.getMessage()
										, JsonTools.toJson(externalResult));
								throw new LogicException("撤销微信订单请求失败");
							}
						} else {
							throw new LogicException("撤销微信订单请求未响应");
						}
					} else {
						throw new LogicException("创建退款订单失败");
					}
				} else {
					throw new LogicException("未获取支付服务");
				}
			}
			JdbcSession.commit();
			return true;
		}catch (SQLException e){
			log.error(e.getMessage(),e);
		}finally {
			JdbcSession.end();
		}
		return false;
	}

	private boolean setLockState(String tradeNo){
		if(StringTools.isNotBlank(tradeNo)) {
			Conditions condition = new Conditions(PayGoodsOrder.class);
			condition.and().is("tradeNo", tradeNo);
			condition.and().is("lockState", ELockState.Idle.index());

			PayGoodsOrder updateEntity = new PayGoodsOrder();
			updateEntity.setLockState(ELockState.Executing.index());

			try {
				return dao.updateNotNull(updateEntity,condition) > 0;
			} catch (SQLException e) {
				log.error(e.getMessage(),e);
			}
		}
		return false;
	}

	private boolean removeLockState(String tradeNo){
		if(StringTools.isNotBlank(tradeNo)) {
			Conditions condition = new Conditions(PayGoodsOrder.class);
			condition.and().is("tradeNo", tradeNo);

			PayGoodsOrder updateEntity = new PayGoodsOrder();
			updateEntity.setLockState(ELockState.Idle.index());

			try {
				return dao.updateNotNull(updateEntity,condition) > 0;
			} catch (SQLException e) {
				log.error(e.getMessage(),e);
			}
		}
		return false;
	}

	/**
	 * 从等待状态 -> 等待发货
	 * @param tradeNo
	 * @return
	 */
	public boolean toWaitDeliver(String tradeNo){
		if(StringTools.isNotBlank(tradeNo)){
			Conditions condition = new Conditions(PayGoodsOrder.class);
			condition.and().is("tradeNo",tradeNo);
			condition.and().is("state",GoodsOrderEnum.State.Wait.index());

			PayGoodsOrder updateEntity = new PayGoodsOrder();
			updateEntity.setState(GoodsOrderEnum.State.WaitDeliver.index());

			try {
				return dao.updateNotNull(updateEntity,condition) > 0;
			} catch (SQLException e) {
				log.error(e.getMessage(),e);
			}
		}
		return false;
	}

	public boolean payResult(WXPayOrder payOrder,OperateInfo operateInfo) {
		PayGoodsOrder simpleTeamPayOrder = getByTradeNo(payOrder.getBusinessTradeNo());
		if(simpleTeamPayOrder != null){
			if (EPayState.Success.index().equals(payOrder.getPayStatus())){
				//支付成功
				if(GoodsOrderEnum.State.Wait.index().equals(simpleTeamPayOrder.getState())) {
					PayGoodsOrderLogItem logItem = new PayGoodsOrderLogItem();
					logItem.setContent(operateInfo.getOperateNote());
					logItem.setProgramType(operateInfo.getProgramType());
					logItem.setOperatorType(operateInfo.getOperatorType());
					logItem.setOperator(operateInfo.getOperator());
					logItem.setCreateDate(new Date());

					if (this.toWaitDeliver(simpleTeamPayOrder.getTradeNo())) {
						logItem.setState(PayGoodsOrderLogEnum.ItemState.Success.index());
						PayGoodsOrderLogService.self().addItem(simpleTeamPayOrder.getTradeNo(),logItem);
						return true;
					}else{
						logItem.setState(PayGoodsOrderLogEnum.ItemState.Error.index());
						logItem.setErrorMsg("修改订单状态失败");
						PayGoodsOrderLogService.self().addItem(simpleTeamPayOrder.getTradeNo(),logItem);
						log.error("支付成功，修改订单状态失败，订单号：{{0}}",simpleTeamPayOrder.getTradeNo());
					}
				}else if(GoodsOrderEnum.State.Close.index().equals(simpleTeamPayOrder.getState())){
					//订单已关闭
					log.error("支付成功，订单已关闭，请做相应处理，订单号：{{0}}",simpleTeamPayOrder.getTradeNo());
				}
			}else{
				log.error("支付未成功，请做相应处理，订单号：{{0}}",simpleTeamPayOrder.getTradeNo());
			}
		}else {
			//团拼中不会创建支付订单，只有当团拼结束后创建
			return TeamPayApplyService.self().payResult(payOrder,operateInfo);
		}
		return false;
	}

	public boolean refundResult(WXPayOrder payOrder,WXRefundOrder refundOrder){
		if(refundOrder != null && payOrder != null) {
			PayGoodsOrder simpleTeamPayOrder = getByTradeNo(payOrder.getBusinessTradeNo());
			if(simpleTeamPayOrder != null){
				PayGoodsOrder updateEntity = new PayGoodsOrder();
				updateEntity.setTradeNo(simpleTeamPayOrder.getTradeNo());
				updateEntity.setState(GoodsOrderEnum.State.Refund.index());

				try {
					if(dao.updateNotNull(updateEntity) > 0){
						//TODO 处理其它情况
						return true;
					}
				} catch (SQLException e) {
					log.error(e.getMessage(),e);
				}
			}
		}
		return false;
	}

	/**
	 * 用于组合支付检查
	 * @param tradeNo
	 * @param operateInfo
	 * @return
	 */
	public boolean checkPaySuccess(String tradeNo,OperateInfo operateInfo){
		PayGoodsOrder goodsOrder = getByTradeNo(tradeNo);
		if(goodsOrder != null && EPayType.WXPay.index().equals(goodsOrder.getPayType())){
			if(GoodsOrderEnum.State.Wait.index().equals(goodsOrder.getState())) {
				//检查所有支付
				List<WXPayOrder> payOrderList = WXPayOrderService.self(goodsOrder.getCreateDate()).findByBusinessTradeNo(tradeNo);
				if (payOrderList != null && payOrderList.size() > 0) {
					boolean flag = true;
					for (WXPayOrder payOrder : payOrderList) {
						if (!EPayState.Success.index().equals(payOrder.getPayStatus())){
							flag = false;
							break;
						}
					}
					if(flag){
						//支付成功，修改订单状态
						flag = this.toWaitDeliver(tradeNo);

						if(flag) {
							PayGoodsOrderLogItem logItem = new PayGoodsOrderLogItem();
							logItem.setContent(operateInfo.getOperateNote());
							logItem.setProgramType(operateInfo.getProgramType());
							logItem.setOperatorType(operateInfo.getOperatorType());
							logItem.setState(PayGoodsOrderLogEnum.ItemState.Success.index());
							logItem.setCreateDate(new Date());
							PayGoodsOrderLogService.self().addItem(tradeNo,logItem);
							return true;
						}
					}
				}
			}else{
				return true;
			}
		}
		return false;
	}

	/**
	 * 关闭订单
	 * @param simpleTeamPayOrder
	 * @param closeReason
	 * @return
	 * @throws LogicException
	 */
	public boolean closeOrder(PayGoodsOrder simpleTeamPayOrder, String closeReason) throws LogicException {
		if(simpleTeamPayOrder != null && StringTools.isNotBlank(closeReason)){
			if(!GoodsOrderEnum.State.Wait.index().equals(simpleTeamPayOrder.getState())){
				throw new LogicException(simpleTeamPayOrder.getStateName() + "订单无法关闭");
			}

			Conditions conditions = new Conditions(PayGoodsOrder.class);
			conditions.and().is("tradeNo",simpleTeamPayOrder.getTradeNo());
			conditions.and().is("state",GoodsOrderEnum.State.Wait.index());

			PayGoodsOrder updateEntity = new PayGoodsOrder();
			updateEntity.setState(GoodsOrderEnum.State.Close.index());
			updateEntity.setCloseReason(closeReason);

			try {
				return dao.updateNotNull(updateEntity,conditions) > 0;
			} catch (SQLException e) {
				log.error(e.getMessage(),e);
			}
		}
		return false;
	}

	/**
	 * 修改收货地址
	 * @param simpleTeamPayOrder
	 * @return
	 * @throws LogicException
	 */
	public boolean updateOrderAddress(PayGoodsOrder simpleTeamPayOrder, MemberAddress memberAddress) throws LogicException {
		if(simpleTeamPayOrder != null && memberAddress != null){
			if(!GoodsOrderEnum.SupplyState.WaitConfirm.index().equals(simpleTeamPayOrder.getSupplyState())
					|| !GoodsOrderEnum.State.WaitDeliver.index().equals(simpleTeamPayOrder.getState())){
				throw new LogicException("商家已确认或已发货，无法修改地址");
			}

			Conditions conditions = new Conditions(PayGoodsOrder.class);
			conditions.and().is("tradeNo", simpleTeamPayOrder.getTradeNo());
			conditions.and().is("supplyState", simpleTeamPayOrder.getSupplyState());
			conditions.and().is("state", simpleTeamPayOrder.getState());

			PayGoodsOrder updateEntity = new PayGoodsOrder();
			updateEntity.setMailAddressId(memberAddress.getId());
			updateEntity.setReceiveName(memberAddress.getReceiveName());
			updateEntity.setReceivePhone(memberAddress.getReceivePhone());
			updateEntity.setReceiveProvince(memberAddress.getProvince());
			updateEntity.setReceiveAddress(memberAddress.getFullAddress());

			JdbcSession.begin();
			try {
				if(dao.updateNotNull(updateEntity, conditions) > 0){
					if(StringTools.isNotBlank(simpleTeamPayOrder.getGoodsCode())) {
						UpdateGoodsOrderAddressRequest apiReq = new UpdateGoodsOrderAddressRequest();
						apiReq.getBody().setTradeNo(simpleTeamPayOrder.getTradeNo());
						apiReq.getBody().setReceiveName(updateEntity.getReceiveName());
						apiReq.getBody().setReceivePhone(updateEntity.getReceivePhone());
						apiReq.getBody().setReceiveProvince(updateEntity.getReceiveProvince());
						apiReq.getBody().setReceiveAddress(updateEntity.getReceiveAddress());

						UpdateGoodsOrderAddressResponse apiResp = CloudGoodsOrderAPIService.self().updateGoodsOrderAddress(apiReq);
						if (apiResp != null) {
							if (DefaultAPICodeConstants.SUCCESS.equals(apiResp.getCode())) {
								JdbcSession.commit();
								return true;
							} else if (StringTools.isNotBlank(apiResp.getMsg())) {
								throw new LogicException(apiResp.getMsg());
							}
						}
					}else{
						JdbcSession.commit();
						return true;
					}
				}
			} catch (SQLException e) {
				log.error(e.getMessage(), e);
			} finally {
				JdbcSession.end();
			}
		}
		return false;
	}

	/**
	 * 确认订单信息
	 * @param simpleTeamPayOrder
	 * @return
	 * @throws LogicException
	 */
	public boolean confirmGoods(PayGoodsOrder goodsOrder, OperateInfo operateInfo) throws LogicException {
		if(StringTools.isNotBlank(goodsOrder.getGoodsCode())){
			//云商品
			Goods simpleTeamPayGoods = GoodsService.self().getById(goodsOrder.getGoodsId());
			if (simpleTeamPayGoods == null) {
				throw new LogicException("商品不存在");
			}

			boolean flag = false;

			Conditions conditions = new Conditions(PayGoodsOrder.class);
			conditions.and().is("tradeNo",goodsOrder.getTradeNo());
			conditions.and().is("supplyState", GoodsOrderEnum.SupplyState.WaitConfirm.index());

			PayGoodsOrder updateEntity = new PayGoodsOrder();
			updateEntity.setSupplyState(GoodsOrderEnum.SupplyState.WaitSupplierConfirm.index());

			JdbcSession.begin();
			try {
				if(dao.updateNotNull(updateEntity,conditions) > 0){
					goodsOrder.setSupplyState(GoodsOrderEnum.SupplyState.WaitSupplierConfirm.index());
					/*if(CloudPayGoodsOrderService.self().add(simpleTeamPayOrder,operateInfo)){
						JdbcSession.commit();
						flag = true;
					}else{
						throw new LogicException("创建云订单无响应");
					}*/
				}
			} catch (SQLException e) {
				log.error(e.getMessage(),e);
			} finally {
				JdbcSession.end();
			}

			if(flag){
				PayGoodsOrderLogItem logItem = new PayGoodsOrderLogItem();
				logItem.setProgramType(operateInfo.getProgramType());
				logItem.setOperatorType(operateInfo.getOperatorType());
				logItem.setOperator(operateInfo.getOperator());
				logItem.setContent("创建云商品订单，等待供应商确认");
				logItem.setState(PayGoodsOrderLogEnum.ItemState.Success.index());
				logItem.setCreateDate(new Date());
				PayOrderLogEvent logEvent = new PayOrderLogEvent(goodsOrder.getTradeNo()
						, goodsOrder.getCreateDate(), logItem);
				DelayHandleService.get().addEvent(logEvent);
				return true;
			}
		}else{
			//自用商品，直接完成确认
			Conditions conditions = new Conditions(PayGoodsOrder.class);
			conditions.and().is("tradeNo",goodsOrder.getTradeNo());
			conditions.and().is("supplyState", GoodsOrderEnum.SupplyState.WaitConfirm.index());

			PayGoodsOrder updateEntity = new PayGoodsOrder();
			updateEntity.setSupplyState(GoodsOrderEnum.SupplyState.FinishConfirm.index());

			try {
				if(dao.updateNotNull(updateEntity,conditions) > 0){
					PayGoodsOrderLogItem logItem = new PayGoodsOrderLogItem();
					logItem.setProgramType(operateInfo.getProgramType());
					logItem.setOperatorType(operateInfo.getOperatorType());
					logItem.setOperator(operateInfo.getOperator());
					logItem.setContent("确认订单");
					logItem.setState(PayGoodsOrderLogEnum.ItemState.Success.index());
					logItem.setCreateDate(new Date());
					PayOrderLogEvent logEvent = new PayOrderLogEvent(goodsOrder.getTradeNo()
							, goodsOrder.getCreateDate(), logItem);
					DelayHandleService.get().addEvent(logEvent);
					return true;
				}
			} catch (SQLException e) {
				log.error(e.getMessage(),e);
			}
		}
		return false;
	}

	public boolean faceSupplyState(String tradeNo,Integer supplyState){
		if(StringTools.isNotBlank(tradeNo) && supplyState != null){
			PayGoodsOrder updateEntity = new PayGoodsOrder();
			updateEntity.setTradeNo(tradeNo);
			updateEntity.setSupplyState(supplyState);

			try {
				return dao.updateNotNull(updateEntity) > 0;
			} catch (SQLException e) {
				log.error(e.getMessage(),e);
			}
		}
		return false;
	}

	/**
	 * 供应商确定订单
	 * @param simpleTeamPayOrder
	 * @param operateInfo
	 * @return
	 */
	public boolean cloudConfirmGoods(PayGoodsOrder simpleTeamPayOrder, Integer suppliyState, OperateInfo operateInfo){
		Conditions conditions = new Conditions(PayGoodsOrder.class);
		conditions.and().is("tradeNo", simpleTeamPayOrder.getTradeNo());
		conditions.and().is("supplyState", GoodsOrderEnum.SupplyState.WaitSupplierConfirm.index());

		PayGoodsOrder updateEntity = new PayGoodsOrder();
		updateEntity.setSupplyState(suppliyState);

		Integer logState = PayGoodsOrderLogEnum.ItemState.Error.index();
		String logError = "修改数据库失败";
		try {
			if (dao.updateNotNull(updateEntity, conditions) > 0) {
				logState = PayGoodsOrderLogEnum.ItemState.Success.index();
				logError = null;
			}
		}catch (SQLException e) {
			log.error(e.getMessage(), e);
		}
		
		PayGoodsOrderLogItem logItem = new PayGoodsOrderLogItem();
		logItem.setProgramType(operateInfo.getProgramType());
		logItem.setOperatorType(operateInfo.getOperatorType());
		logItem.setOperator(operateInfo.getOperator());
		logItem.setContent(operateInfo.getOperateNote());
		logItem.setState(logState);
		logItem.setErrorMsg(logError);
		logItem.setCreateDate(new Date());
		PayOrderLogEvent logEvent = new PayOrderLogEvent(simpleTeamPayOrder.getTradeNo()
				, simpleTeamPayOrder.getCreateDate(), logItem);
		DelayHandleService.get().addEvent(logEvent);
		
		return false;
	}

	/**
	 * 实物商品发货处理
	 * @return
	 */
	public boolean deliveryGoods(PayGoodsOrder simpleTeamPayOrder, String logisticsCompanyId, String logisticsCompany
			, String logisticsCompanyTradeNo, Date deliverGoodsDate, OperateInfo operateInfo) throws LogicException {
		if(StringTools.isBlank(logisticsCompanyTradeNo)){
			throw new LogicException("请填写物流单号");
		}
		if(simpleTeamPayOrder != null && deliverGoodsDate != null){
			if(StringTools.isBlank(simpleTeamPayOrder.getGoodsCode())) {
				//如果不是云商品则检查物流信息
				if (logisticsCompanyId != null) {
					LogisticsCompany logisticsCompanyEntity = LogisticsCompanyService.self().getById(logisticsCompanyId);
					if (logisticsCompanyEntity == null) {
						throw new LogicException("未找到物流公司信息");
					} else {
						logisticsCompany = logisticsCompanyEntity.getName();
					}
				}
			}

			PayGoodsOrder updateEntity = new PayGoodsOrder();
			updateEntity.setTradeNo(simpleTeamPayOrder.getTradeNo());
			updateEntity.setLogisticsCompanyId(logisticsCompanyId);
			updateEntity.setLogisticsCompany(logisticsCompany);
			updateEntity.setLogisticsTradeNo(logisticsCompanyTradeNo);
			updateEntity.setDeliverGoodsDate(deliverGoodsDate);

			if(GoodsOrderEnum.State.WaitReceive.index() > simpleTeamPayOrder.getState()){
				updateEntity.setState(GoodsOrderEnum.State.WaitReceive.index());
			}
			//默认发货已确定
			updateEntity.setSupplyState(GoodsOrderEnum.SupplyState.FinishConfirm.index());

			try {
				if(dao.updateNotNull(updateEntity) > 0){
					PayGoodsOrderLogItem logItem = new PayGoodsOrderLogItem();
					logItem.setProgramType(operateInfo.getProgramType());
					logItem.setOperatorType(operateInfo.getOperatorType());
					logItem.setOperator(operateInfo.getOperator());
					logItem.setContent(operateInfo.getOperateNote());
					logItem.setState(PayGoodsOrderLogEnum.ItemState.Success.index());
					logItem.setCreateDate(new Date());
					PayOrderLogEvent logEvent = new PayOrderLogEvent(simpleTeamPayOrder.getTradeNo()
							, simpleTeamPayOrder.getCreateDate(), logItem);
					DelayHandleService.get().addEvent(logEvent);
					return true;
				}
			} catch (SQLException e) {
				log.error(e.getMessage(),e);
			}
		}
		return false;
	}

	/**
	 * 虚拟商品发货操作
	 * @param simpleTeamPayOrder
	 * @param deliverGoodsDate
	 * @param deliverGoodsNote
	 * @return
	 * @throws LogicException
	 */
	public boolean deliveryGoods(PayGoodsOrder goodsOrder, Date deliverGoodsDate, String deliverGoodsNote, OperateInfo operateInfo) throws LogicException {
		if(goodsOrder != null && deliverGoodsDate != null){
			PayGoodsOrder updateEntity = new PayGoodsOrder();
			updateEntity.setTradeNo(goodsOrder.getTradeNo());
			updateEntity.setDeliverGoodsDate(deliverGoodsDate == null?new Date():deliverGoodsDate);
			updateEntity.setDeliverGoodsNote(deliverGoodsNote);

			if(GoodsOrderEnum.State.WaitReceive.index() > goodsOrder.getState()){
				updateEntity.setState(GoodsOrderEnum.State.WaitReceive.index());
			}
			//默认发货已确定
			updateEntity.setSupplyState(GoodsOrderEnum.SupplyState.FinishConfirm.index());
			
			try {
				if(dao.updateNotNull(updateEntity) > 0){
					PayGoodsOrderLogItem logItem = new PayGoodsOrderLogItem();
					logItem.setProgramType(operateInfo.getProgramType());
					logItem.setOperatorType(operateInfo.getOperatorType());
					logItem.setOperator(operateInfo.getOperator());
					logItem.setContent(operateInfo.getOperateNote());
					logItem.setState(PayGoodsOrderLogEnum.ItemState.Success.index());
					logItem.setCreateDate(new Date());
					PayOrderLogEvent logEvent = new PayOrderLogEvent(goodsOrder.getTradeNo()
							, goodsOrder.getCreateDate(), logItem);
					DelayHandleService.get().addEvent(logEvent);
					return true;
				}
			} catch (SQLException e) {
				log.error(e.getMessage(),e);
			}
		}
		return false;
	}

	/**
	 * 会员收货
	 * @param simpleTeamPayOrder
	 * @param operateInfo
	 * @return
	 * @throws LogicException
	 */
	public boolean receiveGoods(PayGoodsOrder goodsOrder, OperateInfo operateInfo) throws LogicException {
		if(goodsOrder != null){
			if(!GoodsOrderEnum.State.WaitReceive.index().equals(goodsOrder.getState())){
				throw new LogicException(goodsOrder.getStateName() + "订单无法收货");
			}

			Date receiveGoodsDate = new Date();
			if(goodsOrder.getDeliverGoodsDate() != null && goodsOrder.getDeliverGoodsDate().after(receiveGoodsDate)){
				throw new LogicException("正在发货请稍等");
			}

			Conditions conditions = new Conditions(PayGoodsOrder.class);
			conditions.and().is("tradeNo",goodsOrder.getTradeNo());
			conditions.and().is("state",GoodsOrderEnum.State.WaitReceive.index());

			PayGoodsOrder updateEntity = new PayGoodsOrder();
			updateEntity.setState(GoodsOrderEnum.State.WaitEvaluate.index());
			updateEntity.setReceiveGoodsType(EReceiveGoodsType.ClientConfirm.index());
			updateEntity.setReceiveGoodsDate(receiveGoodsDate);

			Boolean flag = false;
			try {
				if(dao.updateNotNull(updateEntity,conditions) > 0){
					flag = true;
				}
			} catch (SQLException e) {
				log.error(e.getMessage(),e);
			}

			if(flag){
				//处理操作日志
				PayGoodsOrderLogItem logItem = new PayGoodsOrderLogItem();
				logItem.setProgramType(operateInfo.getProgramType());
				logItem.setOperatorType(operateInfo.getOperatorType());
				logItem.setOperator(operateInfo.getOperator());
				logItem.setContent("确定收货");
				logItem.setState(PayGoodsOrderLogEnum.ItemState.Success.index());
				logItem.setCreateDate(new Date());
				PayOrderLogEvent logEvent = new PayOrderLogEvent(goodsOrder.getTradeNo()
						, goodsOrder.getCreateDate(), logItem);
				DelayHandleService.get().addEvent(logEvent);

				if(StringTools.isNotBlank(goodsOrder.getGoodsCode())){
					/*CloudPayGoodsOrder supplierGoodsOrder = CloudPayGoodsOrderService.self().getByTradeNo(simpleTeamPayOrder.getTradeNo());
					if(supplierGoodsOrder != null) {
						CloudPayGoodsOrderService.self().receiveGoods(supplierGoodsOrder,updateEntity.getReceiveGoodsType(),updateEntity.getReceiveGoodsDate());
					}else{
						log.error("收货处理，未找到云订单信息，订单号：{{0}}",simpleTeamPayOrder.getTradeNo());
					}*/
				}
				return true;
			}
		}
		return false;
	}

	/**
	 * 自定义收货
	 * @param simpleTeamPayOrder
	 * @param receiveGoodsType
	 * @param receiveGoodsDate
	 * @param operateInfo
	 * @return
	 * @throws LogicException
	 */
	public boolean receiveGoods(PayGoodsOrder simpleTeamPayOrder, Integer receiveGoodsType, Date receiveGoodsDate, OperateInfo operateInfo) throws LogicException {
		if(simpleTeamPayOrder != null){
			if(!GoodsOrderEnum.State.WaitReceive.index().equals(simpleTeamPayOrder.getState())){
				throw new LogicException(simpleTeamPayOrder.getStateName() + "订单无法收货");
			}

			if(simpleTeamPayOrder.getDeliverGoodsDate() != null && simpleTeamPayOrder.getDeliverGoodsDate().after(receiveGoodsDate)){
				throw new LogicException("正在发货请稍等");
			}

			Conditions conditions = new Conditions(PayGoodsOrder.class);
			conditions.and().is("tradeNo",simpleTeamPayOrder.getTradeNo());
			conditions.and().is("state",GoodsOrderEnum.State.WaitReceive.index());

			PayGoodsOrder updateEntity = new PayGoodsOrder();
			updateEntity.setState(GoodsOrderEnum.State.WaitEvaluate.index());
			updateEntity.setReceiveGoodsType(receiveGoodsType);
			updateEntity.setReceiveGoodsDate(receiveGoodsDate);

			Boolean flag = false;
			try {
				if(dao.updateNotNull(updateEntity,conditions) > 0){
					flag = true;
				}
			} catch (SQLException e) {
				log.error(e.getMessage(),e);
			}

			if(flag){
				//处理操作日志
				PayGoodsOrderLogItem logItem = new PayGoodsOrderLogItem();
				logItem.setProgramType(operateInfo.getProgramType());
				logItem.setOperatorType(operateInfo.getOperatorType());
				logItem.setOperator(operateInfo.getOperator());
				logItem.setContent("确定收货");
				logItem.setState(PayGoodsOrderLogEnum.ItemState.Success.index());
				logItem.setCreateDate(new Date());
				PayOrderLogEvent logEvent = new PayOrderLogEvent(simpleTeamPayOrder.getTradeNo()
						, simpleTeamPayOrder.getCreateDate(), logItem);
				DelayHandleService.get().addEvent(logEvent);

				if(StringTools.isNotBlank(simpleTeamPayOrder.getGoodsCode())){
					/*CloudPayGoodsOrder supplierGoodsOrder = CloudPayGoodsOrderService.self().getByTradeNo(simpleTeamPayOrder.getTradeNo());
					if(supplierGoodsOrder != null) {
						CloudPayGoodsOrderService.self().receiveGoods(supplierGoodsOrder,updateEntity.getReceiveGoodsType(),updateEntity.getReceiveGoodsDate());
					}else{
						log.error("收货处理，未找到云订单信息，订单号：{{0}}",simpleTeamPayOrder.getTradeNo());
					}*/
				}
				return true;
			}
		}
		return false;
	}

	/**
	 * 评价商品处理
	 * @return
	 */
	public boolean evaluateGoods(PayGoodsOrder simpleTeamPayOrder, OperateInfo operateInfo) throws LogicException {
		if(simpleTeamPayOrder != null && StringTools.isNotBlank(simpleTeamPayOrder.getTradeNo())) {
			Conditions conditions = new Conditions(PayGoodsOrder.class);
			conditions.and().is("tradeNo", simpleTeamPayOrder.getTradeNo());
			conditions.and().is("state", GoodsOrderEnum.State.WaitEvaluate.index());

			PayGoodsOrder updateEntity = new PayGoodsOrder();
			updateEntity.setState(GoodsOrderEnum.State.Finish.index());

			boolean flag = false;
			try {
				if (dao.updateNotNull(updateEntity, conditions) > 0) {
					PayGoodsOrderLogItem logItem = new PayGoodsOrderLogItem();
					logItem.setProgramType(operateInfo.getProgramType());
					logItem.setOperatorType(operateInfo.getOperatorType());
					logItem.setOperator(operateInfo.getOperator());
					logItem.setContent(operateInfo.getOperateNote());
					logItem.setState(PayGoodsOrderLogEnum.ItemState.Success.index());
					logItem.setCreateDate(new Date());
					PayOrderLogEvent logEvent = new PayOrderLogEvent(simpleTeamPayOrder.getTradeNo()
							, simpleTeamPayOrder.getCreateDate(), logItem);
					DelayHandleService.get().addEvent(logEvent);
					flag = true;
				}
			} catch (SQLException e) {
				log.error(e.getMessage(), e);
			}

			if (flag) {
				//TODO 触发云事件
				return true;
			}
		}
		return false;
	}

	public boolean deleteByTradeNo(String tradeNo) throws LogicException{
		if(StringTools.isNotBlank(tradeNo)) {
			JdbcSession.begin();
			try {
				if(dao.deleteById(tradeNo) > 0) {
					if(PayGoodsOrderLogService.self(dao.getJdbcKey()).deleteByTradeNo(tradeNo)) {
						if(PayGoodsOrderLogisticsService.self(dao.getJdbcKey()).deleteByTradeNo(tradeNo)) {
							JdbcSession.commit();
							return true;
						}
					}
				}
			}catch(SQLException e) {
				
			}finally {
				JdbcSession.end();
			}
		}
		return false;
	}
}
